package com.mec.fileTransfer.core;

import java.io.RandomAccessFile;
import java.util.concurrent.ThreadPoolExecutor;

import com.mec.fileTransfer.view.IResourceReceiveProgress;

/**
 * 服务器接收到的文件资源块。
 * 其中的线程一旦被启动，将在文件系统中独立的
 * 作为一个线程将自己的内容写入到磁盘中。这里的线程是基于线程池的管理的。
 * 并且在写入完成之后作出相应善后工作。包括：
 * 将进度条更新；
 * 更新RFM中的文件资源表示块。
 * @author Lconf
 *
 */
public class ResourceBlock implements Runnable {
	private long offset;
	private int length;
	private byte[] context;
	private ReceiveFileModel rfm;
	private ThreadPoolExecutor threadPool;
	private IResourceReceiveProgress receiveProgress;
	private int fileId;
	
	protected ResourceBlock setFileId(int fileId) {
		this.fileId = fileId;
		
		return this;
	}

	ResourceBlock() {
	}
	
	protected ResourceBlock(long offset, int length, byte[] context, ReceiveFileModel rfm,
			ThreadPoolExecutor threadpool, IResourceReceiveProgress receiveProgress) {
		this();
		this.offset = offset;
		this.length = length;
		this.context = context;
		this.rfm = rfm;
		this.threadPool = threadpool;
		this.receiveProgress = receiveProgress;
	}

	protected long getOffset() {
		return offset;
	}

	protected void setOffset(long offset) {
		this.offset = offset;
	}

	protected int getLength() {
		return length;
	}

	protected void setLength(int length) {
		this.length = length;
	}

	protected byte[] getContext() {
		return context;
	}

	protected void setContext(byte[] context) {
		this.context = context;
	}

	protected ReceiveFileModel getRfm() {
		return rfm;
	}

	protected void setRfm(ReceiveFileModel rfm) {
		this.rfm = rfm;
	}
	
	void startWirte() {
		threadPool.execute(this);
	}
	
	//提供用于run方法中的将receiveModel中的内容写入到磁盘中的write方法
	void writeToDisk(ReceiveFileModel rfm) throws Exception {
		String absolutePath = rfm.getAbsolutePath();
		String filePath = rfm.getFilePath();
		//RandomAccessFile raf = new RandomAccessFile(filePath + absolutePath, "rwd");
		RandomAccessFile raf = RamdomAccessFlieBuffer.getRafFromBuffer(filePath + absolutePath);
		if(raf == null) {
			System.out.println("resourceBlock: writing file error. " +
					"there was no file found by the path:'" + filePath + absolutePath + "'");
			return;
		}
		raf.seek(offset);
		raf.write(context);
		
		if (receiveProgress != null) {
			receiveProgress.receiveOneBlock(fileId, context.length);
		}
	}

	@Override
	public void run() {
		try {
			//这里先将内容写入磁盘，并且调用了重新整合未接收的文件碎片列表的方法。
			writeToDisk(rfm);
			rfm.getUbi().receiveBlock(this);
		} catch (Exception e) {
			// 写入失败或者写入过程中发生异常
			e.printStackTrace();
		}		
	}
	
}
